package.cpath = package.cpath..';./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;'
require('wx')
require('task')
require('buffer')

function task.fromfile(filename)
	local f=io.open(filename,'r')
	local r=task.create()
	r:dostring(f:read('*a'))
	return r
end

ccd_task=task.fromfile('.\\CCD background.lua')

function main()
	-- dc of image
	local bitmapdc=wx.wxMemoryDC()
	-- matrix
	tran_matrix={1,0,0,1}
	local function matrix_mult(a,b) --a*b
		r={}
		r[1]=a[1]*b[1]+a[2]*b[3]
		r[2]=a[1]*b[2]+a[2]*b[4]
		r[3]=a[3]*b[1]+a[4]*b[3]
		r[4]=a[3]*b[2]+a[4]*b[4]
		return r
	end
	--
	-- load xrc layout
	local xmlres=wx.wxXmlResource()
    xmlres:InitAllHandlers()
    xmlres:Load'.\\CCD Viewer.xrc'
	--
	-- load dialog
	local dialog=wx.wxDialog()
	xmlres:LoadDialog(dialog,wx.NULL,'dialog')
	local image_window=wx.wxDialog()
	xmlres:LoadDialog(image_window,wx.NULL,'image_window')
	local large_image=false
	--
	-- load controls
	dialog.ctrlid={}
	for _,id in pairs{'ctrl_status','ctrl_rot_1','ctrl_flip_v','ctrl_snapshot','ctrl_flip_h','ctrl_rot_2'} do
		dialog.ctrlid[id]=xmlres.GetXRCID(id)
	end
	local status_display=dialog:FindWindow(dialog.ctrlid.ctrl_status)
	status_display:DynamicCast('wxStaticText')
	--
	-- bind events
	local counter_idle=0
	dialog:Connect(wx.wxEVT_IDLE,function(event)
		counter_idle=counter_idle+1
		local imgptr=ccd_task:get('imgptr')
		if imgptr then
			local image=wx.wxImage(512,512,buffer.ptrtostring(imgptr,512*512*3),true)
			local bmp
			if large_image then bmp=wx.wxBitmap(image:Scale(1024,1024)) else bmp=wx.wxBitmap(image) end
			bitmapdc:SelectObject(bmp)
			if large_image then wx.wxClientDC(image_window):Blit(0,0,1024,1024,bitmapdc,0,0)
			else wx.wxClientDC(image_window):Blit(0,0,512,512,bitmapdc,0,0) end
			if counter_idle%32==0 then
				local sts,msg=ccd_task:status()
				if sts=='error' then print(msg) end
				status_display:SetLabel(string.format('exp_time=% 5dus\nmin=% 5d\nmax=% 5d\navg=% 5d\npoint_size=% 7d\npoint_value=% 5d\npoint_pos=(% 3d,% 3d)',
					ccd_task:get('exp_time'),
					ccd_task:get('minv'),
					ccd_task:get('maxv'),
					ccd_task:get('avg'),
					ccd_task:get('point_size'),
					ccd_task:get('point_value'),
					ccd_task:get('point_x'),
					ccd_task:get('point_y')
				))
			end
			image=nil
			bmp=nil
		end
		event:RequestMore()
		event:Skip()
	end)
	dialog:Connect(wx.wxEVT_CLOSE_WINDOW,function(event)
		ccd_task:set('quit_flag',true)
		image_window:Close()
		event:Skip()
	end)
	local function update_matrix()
		if tran_matrix[1]~=0 then
			ccd_task:set('flipx',tran_matrix[1]==-1)
			ccd_task:set('flipy',tran_matrix[4]==-1)
			ccd_task:set('swapxy',false)
		else
			ccd_task:set('flipx',tran_matrix[3]==-1)
			ccd_task:set('flipy',tran_matrix[2]==-1)
			ccd_task:set('swapxy',true)
		end
	end
	dialog:Connect(dialog.ctrlid.ctrl_flip_h,wx.wxEVT_COMMAND_BUTTON_CLICKED,function(event)
		tran_matrix=matrix_mult({-1,0,0,1},tran_matrix)
		update_matrix()
		event:Skip()
	end)
	dialog:Connect(dialog.ctrlid.ctrl_flip_v,wx.wxEVT_COMMAND_BUTTON_CLICKED,function(event)
		tran_matrix=matrix_mult({1,0,0,-1},tran_matrix)
		update_matrix()
		event:Skip()
	end)
	dialog:Connect(dialog.ctrlid.ctrl_rot_1,wx.wxEVT_COMMAND_BUTTON_CLICKED,function(event)
		tran_matrix=matrix_mult({0,-1,1,0},tran_matrix)
		update_matrix()
		event:Skip()
	end)
	dialog:Connect(dialog.ctrlid.ctrl_rot_2,wx.wxEVT_COMMAND_BUTTON_CLICKED,function(event)
		tran_matrix=matrix_mult({0,1,-1,0},tran_matrix)
		update_matrix()
		event:Skip()
	end)
	dialog:Connect(dialog.ctrlid.ctrl_snapshot,wx.wxEVT_COMMAND_BUTTON_CLICKED,function(event)
		local imgptr=ccd_task:get('imgptr')
		if imgptr then
			local image=wx.wxImage(512,512,buffer.ptrtostring(imgptr,512*512*3),true)
			image:SaveFile('.\\CCD snapshot\\'..os.date("!%Y-%m-%d-%H-%M-%S",os.time()+28800)..'.png',wx.wxBITMAP_TYPE_PNG)
		end
		event:Skip()
	end)
	image_window:Connect(wx.wxEVT_LEFT_DCLICK,function(event)
		large_image=not large_image
		if large_image then image_window:SetClientSize(1024,1024)
		else image_window:SetClientSize(512,512) end
		event:Skip()
	end)
	--
	-- show dialogs
	dialog:Show(true)
	image_window:Show(true)
end

main()
wx.wxGetApp():MainLoop()
